home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / tasm_vid.zip / VIDEO.ASM < prev    next >
Assembly Source File  |  1988-11-09  |  26KB  |  855 lines

  1. TITLE 'Direct Video Routines'
  2.  
  3. ;
  4. ; Author: David Bennett - Version 1.0 - Date: 11/9/88
  5. ;
  6. ; This is a module of direct video writing routines for TASM.  Please see the
  7. ; file VIDEO.DOC for more information.  Examples of most routines are set forth
  8. ; in VIDDEMO.ASM.
  9. ;
  10. ; -Dave
  11.  
  12. IDEAL                   ; Uses TASM's IDEAL mode  (Get used to this!)
  13.  
  14. MODEL SMALL             ; Small memory model
  15.  
  16. INCLUDE 'VIDEO.INC'     ; Equates / Global decs etc...
  17.  
  18. ; ------
  19. ; Macros
  20. ; ------
  21.  
  22. MACRO   WaitRetrace
  23.     LOCAL   WaitNoH, WaitH, End
  24.     ;
  25.     ; This macro waits for the horizontial retrace signal from the
  26.     ; monitor before continuing. Interrupts should be disabled B4
  27.     ; calling this routine with CLI. Of course, make sure int's are
  28.     ; reenabled afterwards with STI.
  29.     ;
  30.     ; Modifies
  31.     ;       DX, AL
  32.     ;
  33.         mov     dx, 3DAh                ; CGA status register
  34.     WaitNoH:
  35.         in      al, dx                  ; Get 6845 Status
  36.         test    al,8                    ; Check vert retrace
  37.         jnz     End                     ;   In Progress? go
  38.         rcr     al,1                    ; Wait for end of
  39.         jc      WaitNoH                 ;   horizontial retrace
  40.     WaitH:
  41.         in      al, dx                  ; Get 6845 status again
  42.         rcr     al, 1                   ; Wait for horizontial
  43.         jnc     WaitH                   ;   retrace
  44.     End:
  45. ENDM
  46.  
  47. DATASEG
  48.  
  49.     GLOBAL BaseOfScreen:WORD
  50.     GLOBAL SnowCheck:BYTE
  51.     GLOBAL VideoMode:BYTE
  52.  
  53.     BaseOfScreen    DW      CGASeg          ; Offset for current vid mode
  54.     SnowCheck       DB      0               ; Check for retrace 1/0
  55.     VideoMode       DB      0               ; Current BIOS INT 10 vid mode
  56.  
  57. ; ---------
  58. ; Code area
  59. ; ---------
  60.  
  61. CODESEG
  62.  
  63. ; ----------------
  64. ; Video Procedures
  65. ; ----------------
  66.  
  67.     PROC MoveXY_DI
  68.     ;
  69.     ; This procedure moves to the offset indicated by an X & Y cusor
  70.     ; location.
  71.     ;
  72.     ; Input
  73.     ;       AH = Row
  74.     ;       AL = Column
  75.     ; Output
  76.     ;       DI = Memory Offset
  77.     ;
  78.         push    cx              ; Save CX
  79.         xor     cl, cl          ; Clear CL
  80.         mov     ch, ah          ; CX = Row * 256
  81.         dec     ch              ; CX = (Row - 1) {0-24 Based}
  82.         shr     cx, 1           ; CX = Row * 128
  83.         mov     di, cx          ; Store in DI
  84.         shr     di, 1           ; DI = Row * 64
  85.         shr     di, 1           ; DI = Row * 32
  86.         add     di, cx          ; DI = (Row * 128)+(Row * 32) {Row*160}
  87.         xor     ch, ch          ; Clear CH register
  88.         mov     cl, al          ; CX = Columns
  89.         dec     cx              ; Make 0-79
  90.         shl     cx, 1           ; Account for attribute
  91.         add     di, cx          ; DI = (Row * 160) + (Col * 2)
  92.         pop     cx              ; Restore CX register
  93.         ret
  94.  
  95.     ENDP MoveXY_DI
  96.  
  97.     PROC MoveXY_SI
  98.     ;
  99.     ; This procedure moves to the offset indicated by an X & Y cusor
  100.     ; location.
  101.     ;
  102.     ; Input
  103.     ;       AH = Row
  104.     ;       AL = Column
  105.     ; Output
  106.     ;       SI = Memory Offset - Points 1 byte beyond null of str displayed
  107.     ;
  108.         push    cx              ; Save CX
  109.         xor     cl, cl          ; Clear CL
  110.         mov     ch, ah          ; CX = Row * 256
  111.         dec     ch              ; CX = (Row - 1) {0-24 Based}
  112.         shr     cx, 1           ; CX = Row * 128
  113.         mov     si, cx          ; Store in SI
  114.         shr     si, 1           ; SI = Row * 64
  115.         shr     si, 1           ; SI = Row * 32
  116.         add     si, cx          ; SI = (Row * 128)+(Row * 32) {Row*160}
  117.         xor     ch, ch          ; Clear CH register
  118.         mov     cl, al          ; CX = Columns
  119.         dec     cx              ; Make 0-79
  120.         shl     cx, 1           ; Account for attribute
  121.         add     si, cx          ; DI = (Row * 160) + (Col * 2)
  122.         pop     cx              ; Restore CX register
  123.         ret
  124.  
  125.     ENDP MoveXY_SI
  126.  
  127.     GLOBAL  EGAInstalled:PROC
  128.     PROC    EGAInstalled
  129.     ;
  130.     ; This procedure checks to see if the current adapter card is an
  131.     ; EGA.
  132.     ;
  133.     ; Output
  134.     ;       AL = 1 if EGA Adapter is found / 0 if not
  135.     ; Modified
  136.     ;       AX
  137.     ;
  138.         push    bx              ; Store used registers
  139.         push    cx
  140.         mov     ax, 1200h       ; BIOS INT 10 function 12h
  141.         mov     bx, 10h         ; sub-func 10h (Get EGA info)
  142.         mov     cx, 0FFFFh      ; lite all bits of CX
  143.         int     10h             ; call INT 10
  144.         xor     ax, ax          ; Clear AX reg
  145.         cmp     cx, 0FFFFh      ; If CX not modified by INT call
  146.         je      EI_Done         ;   then this is not an EGA
  147.         inc     AL              ; Increment AL to show this is EGA
  148.     EI_Done:
  149.         pop     cx              ; Restore regs
  150.         pop     bx
  151.         ret
  152.  
  153.     ENDP EGAInstalled
  154.  
  155.     GLOBAL  GetVideoMode:PROC
  156.     PROC    GetVideoMode
  157.     ;
  158.     ; This procedure checks the video mode and sets the BaseOfScreen
  159.     ; accordingly.  It also sets SnowCheck to 1 if adapter is a CGA.
  160.     ;
  161.     ; Output
  162.     ;       BaseOfScreen
  163.     ;       VideoMode
  164.     ;       SnowCheck
  165.     ; Uses
  166.     ;       EGAInstalled
  167.     ;
  168.         push    ax                      ; Store registers
  169.         push    di
  170.         push    ds
  171.         mov     ax, @data               ; Move DATASEG segment
  172.         mov     ds, ax                  ;   into DS registers
  173.         mov     di, CGASeg              ; move offset of CGA to DI
  174.         mov     ah, 0Fh                 ; INT 10 get vid mode func
  175.         int     10h                     ; get the video mode
  176.         xor     ah, ah                  ; clear the AH reg
  177.         mov     [VideoMode], al         ; place mode into VideoMode
  178.         cmp     al, 7                   ; Is this a mono screen?
  179.         jne     NotMono                 ; if not jump to NotMono
  180.         mov     di, MonoSeg             ; move offset of mono to DI
  181.         mov     [SnowCheck], 0          ; NEVER CHECK RETRACE ON MONO!
  182.         jmp     GVM_Done
  183.     NotMono:                                ; Process CGA/EGA/VGA adap.
  184.         call    EGAInstalled            ; Check for EGA adap.
  185.         rcr     al, 1                   ; Move bit 1 to carry flag
  186.         jc      GVM_Done                ; If EGA then no snow check
  187.         mov     [SnowCheck], 1          ; Not EGA so set snow check
  188.     GVM_Done:
  189.         mov     [BaseOfScreen], di      ; Move DI to base of screen
  190.         pop     ds                      ; Restore regs
  191.         pop     di
  192.         pop     ax
  193.         ret
  194.  
  195.     ENDP GetVideoMode
  196.  
  197.     GLOBAL  DWriteCH:PROC
  198.     PROC    DWriteCH
  199.     ;
  200.     ; Writes a character to the screen using direct memory access.
  201.     ;
  202.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  203.     ;
  204.     ; Input
  205.     ;       AH      Row on screen 1-25
  206.     ;       AL      Column on screen 1-80
  207.     ;       BH      Video Attribute
  208.     ;       BL      Character
  209.     ;       CX      Number of times
  210.     ; Output
  211.     ;       Screen memory (B000:0000 or 8000 CGA/MONO
  212.     ;
  213.         push    ax              ; Store the registers
  214.         push    cx
  215.         push    dx
  216.         push    es
  217.         push    di
  218.  
  219.         call    MoveXY_DI       ; Set DI to row / column offset
  220.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  221.         mov     al, [SnowCheck]         ; Move snow check to al
  222.         rcr     al, 1           ; SnowCheck
  223.         jnc     DWC_NoWait      ; if no snowcheck goto FW_NoWait
  224.     DWC_Next:
  225.         cli                     ; Disable interrupts
  226.         WaitRetrace             ; Macro to wait for horiz retrace
  227.         mov     ax, bx          ; Move char/attr into AX
  228.         stosw                   ; Move char/attr to screen
  229.         sti                     ; Enable interrupts
  230.         loop    DWC_Next        ; Repeat CX times
  231.         jmp     DWC_Exit        ; Exit this routine
  232.     DWC_NoWait:
  233.         mov     ax, bx          ; Move char/attr into AX
  234.         rep     stosw           ; Move char/attr to screen CX times
  235.  
  236.     DWC_Exit:
  237.         pop     di              ; Restore the registers
  238.         pop     es
  239.         pop     dx
  240.         pop     cx
  241.         pop     ax
  242.         ret
  243.  
  244.     ENDP    DWriteCH
  245.  
  246.     GLOBAL  DWriteCHNA:PROC
  247.     PROC    DWriteCHNA
  248.     ;
  249.     ; Writes a character to the screen using direct memory access.
  250.     ; This procedure does not disturb current attr setting.
  251.     ;
  252.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  253.     ;
  254.     ; Input
  255.     ;       AH      Row on screen 1-25
  256.     ;       AL      Column on screen 1-80
  257.     ;       BL      Character
  258.     ;       CX      Number of times
  259.     ; Output
  260.     ;       Screen memory (B000:0000 or 8000 CGA/MONO
  261.     ;
  262.         push    ax              ; Store the registers
  263.         push    cx
  264.         push    dx
  265.         push    es
  266.         push    di
  267.  
  268.         call    MoveXY_DI       ; Set DI to row / column offset
  269.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  270.         mov     al, [SnowCheck]         ; Move snow check to al
  271.         rcr     al, 1           ; SnowCheck
  272.         jnc     DWCN_NoWait     ; if no snowcheck goto FW_NoWait
  273.     DWCN_Next:
  274.         cli                     ; Disable interrupts
  275.         WaitRetrace             ; Macro to wait for horiz retrace
  276.         mov     al, bl          ; Move char into al
  277.         stosb                   ; Move char to screen
  278.         sti                     ; Enable interrupts
  279.         inc     di              ; Skip over attr
  280.         loop    DWCN_Next       ; Repeat CX times
  281.         jmp     DWCN_Exit       ; Exit this routine
  282.     DWCN_NoWait:
  283.         mov     al, bl          ; Move char into AX
  284.     DWCN_NoWaitLoop:
  285.         stosb                   ; Move char to screen
  286.         inc     di              ; Skip over attr
  287.         loop    DWCN_NoWaitLoop ; Repeat CX times
  288.  
  289.     DWCN_Exit:
  290.         pop     di              ; Restore the registers
  291.         pop     es
  292.         pop     dx
  293.         pop     cx
  294.         pop     ax
  295.         ret
  296.  
  297.     ENDP    DWriteCHNA
  298.  
  299.     GLOBAL  DWriteStr:PROC
  300.     PROC    DWriteStr
  301.     ;
  302.     ; This procedure writes a null delimited string to the screen using
  303.     ; direct memory access.
  304.     ;
  305.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  306.     ;
  307.     ; Input
  308.     ;       DS:SI   Null terminated string to print
  309.     ;       AH      Row on screen 1-25
  310.     ;       AL      Column on screen 1-80
  311.     ;       BH      Video Attribute
  312.     ; Output
  313.     ;       Screen memory (B000:0000 or 8000 CGA/MONO
  314.     ; Modifies
  315.     ;       SI - Points 1 byte beyond null of str displayed
  316.     ;
  317.         push    ax              ; Store the registers
  318.         push    bx
  319.         push    cx
  320.         push    dx
  321.         push    es
  322.         push    di
  323.  
  324.         call    MoveXY_DI       ; Set DI to row / column offset
  325.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  326.         mov     cl, [SnowCheck]         ; Move snow check to al
  327.         cld                     ; Clear the direction flag
  328.         rcr     cl, 1           ; SnowCheck
  329.         mov     ah, bh          ; Place video attr in AH
  330.         jnc     DWS_NoWait      ; if no snowcheck goto DWS_NoWait
  331.     DWS_Next:
  332.         lodsb                   ; Get a character from source
  333.         or      al, al          ; Check for NULL
  334.         jz      DWS_Exit        ; If NULL then exit
  335.         mov     bx, ax          ; Store video word into BX
  336.         cli                     ; Disable interrupts
  337.         WaitRetrace             ; Macro to wait for horiz retrace
  338.         mov     ax, bx          ; Move word back to AX...
  339.         stosw                   ; Move word to screen
  340.         sti                     ; Enable interrupts
  341.         jmp     DWS_Next        ; Continue
  342.     DWS_NoWait:
  343.         lodsb                   ; Get a character from string
  344.         or      al, al          ; Check for NULL
  345.         jz      DWS_Exit        ; If NULL then exit
  346.         stosw                   ; Move word to screen
  347.         loop    DWS_NoWait      ; Continue
  348.     DWS_Exit:
  349.         pop     di              ; Restore the registers
  350.         pop     es
  351.         pop     dx
  352.         pop     cx
  353.         pop     bx
  354.         pop     ax
  355.         ret
  356.  
  357.     ENDP    DWriteStr
  358.  
  359.     GLOBAL  DWriteStrNA:PROC
  360.     PROC    DWriteStrNA
  361.     ;
  362.     ; This procedure writes a null delimited string to the screen using
  363.     ; direct memory access, attribute is not changed.
  364.     ;
  365.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  366.     ;
  367.     ; Input
  368.     ;       DS:SI   Null terminated string to print
  369.     ;       AH      Row on screen 1-25
  370.     ;       AL      Column on screen 1-80
  371.     ; Output
  372.     ;       Screen memory (B000:0000 or 8000 CGA/MONO)
  373.     ; Modifies
  374.     ;       SI - Points 1 byte beyond null of str displayed
  375.     ;
  376.         push    ax              ; Store the registers
  377.         push    bx
  378.         push    cx
  379.         push    dx
  380.         push    es
  381.         push    di
  382.  
  383.         call    MoveXY_DI       ; Set DI to screen offset pos
  384.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  385.         mov     cl, [SnowCheck]         ; Move snow check to cl
  386.         cld                     ; Clear the direction flag
  387.         rcr     cl, 1           ; SnowCheck
  388.         jnc     DWSN_NoWait     ; if no snowcheck goto DWSN_NoWait
  389.     DWSN_Next:
  390.         lodsb                   ; Get a character from source
  391.         or      al, al          ; Check for NULL
  392.         jz      DWSN_Exit       ; If NULL then exit
  393.         mov     bx, ax          ; Store video word into BX
  394.         cli                     ; Turn off interrupts
  395.         WaitRetrace             ; Macro - Waits for horiz retrace
  396.         mov     ax, bx          ; Move word back to AX...
  397.         stosb                   ; Move word to screen
  398.         sti                     ; Enable interrupts
  399.         inc     di              ; Skip the attribute.
  400.         jmp     DWSN_Next       ; Continue
  401.     DWSN_NoWait:
  402.         lodsb                   ; Get a character from string
  403.         or      al, al          ; Check for NULL
  404.         jz      DWSN_Exit       ; If NULL then exit
  405.         stosb                   ; Store the byte on screen
  406.         inc     di              ; Skip attribute byte
  407.         loop    DWSN_NoWait     ; Continue
  408.     DWSN_Exit:
  409.         pop     di              ; Restore the registers
  410.         pop     es
  411.         pop     dx
  412.         pop     cx
  413.         pop     bx
  414.         pop     ax
  415.         ret
  416.  
  417.     ENDP DWriteStrNA
  418.  
  419.     GLOBAL  DFillCH:PROC
  420.     PROC    DFillCH
  421.     ;
  422.     ; This procedure fills an area of the screen with the specified
  423.     ; character and attribute.
  424.     ;
  425.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  426.     ;
  427.     ; Input
  428.     ;       AH      = Top Row
  429.     ;       AL      = Left Column
  430.     ;       BH      = Number of rows
  431.     ;       BL      = Number of columns
  432.     ;       DH      = Attribute
  433.     ;       DL      = Character
  434.     ;
  435.         push    ax                      ; Store Registers
  436.         push    bx
  437.         push    cx
  438.         push    dx
  439.         push    es
  440.         push    di
  441.  
  442.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  443.         mov     cl, [SnowCheck]         ; Move snow check to CL
  444.  
  445.         cld                     ; Clear the direction flag
  446.         rcr     cl, 1           ; SnowCheck
  447.         mov     ch, 0           ; Clear CH
  448.         jnc     DFC_NoWait      ; if no snowcheck goto DFC_NoWait
  449.  
  450.     DFC_Top:
  451.         mov     cl, bl          ; Load the number of columns
  452.         call    MoveXY_DI       ; Set DI to screen offset pos
  453.         push    ax              ; Store Registers AX, BX
  454.         push    bx
  455.  
  456.     DFC_Next:
  457.         cli                     ; Turn off interrupts
  458.         push    dx              ; Store video word
  459.         WaitRetrace             ; Macro - Waits for horiz retrace
  460.         pop     dx              ; Restore video word
  461.         mov     ax, dx          ; Move word into AX
  462.         stosw                   ; Move word to screen
  463.         sti                     ; Enable interrupts
  464.         loop    DFC_Next        ; Continue
  465.  
  466.         pop     bx              ; Restore registers BX, AX
  467.         pop     ax
  468.         inc     ah              ; Next row
  469.         dec     bh              ; Decrement the number of rows done
  470.         or      bh, bh          ; Check Number of columns
  471.         jnz     DFC_Top         ; Do next column if not done
  472.         jmp     DFC_Exit        ; Exit routine
  473.  
  474.     DFC_NoWait:
  475.         mov     cl, bl          ; Load the number of columns
  476.         call    MoveXY_DI       ; Set DI to screen offset pos
  477.         push    ax              ; Store the char/attr
  478.         mov     ax, dx          ; Move char/attr into ax
  479.         rep     stosw           ; Thats it!
  480.         pop     ax              ; Restore the char/attr
  481.         inc     ah              ; Next row
  482.         dec     bh              ; Decrement number of rows done
  483.         or      bh, bh          ; Check number of columns
  484.         jnz     DFC_NoWait      ; Do next column
  485.  
  486.     DFC_Exit:
  487.         pop     di              ; Restore registers
  488.         pop     es
  489.         pop     dx
  490.         pop     cx
  491.         pop     bx
  492.         pop     ax
  493.         ret
  494.  
  495.     ENDP DFillCH
  496.  
  497.     GLOBAL  DFillCHNA:PROC
  498.     PROC    DFillCHNA
  499.     ;
  500.     ; This procedure fills an area of the screen with the specified
  501.     ; character. Attribute remains the same.
  502.     ;
  503.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  504.     ;
  505.     ; Input
  506.     ;       AH      = Top Row
  507.     ;       AL      = Left Column
  508.     ;       BH      = Number of rows
  509.     ;       BL      = Number of columns
  510.     ;       DL      = Character
  511.     ;
  512.         push    ax                      ; Store Registers
  513.         push    bx
  514.         push    cx
  515.         push    dx
  516.         push    es
  517.         push    di
  518.  
  519.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  520.         mov     cl, [SnowCheck]         ; Move snow check to CL
  521.  
  522.         cld                     ; Clear the direction flag
  523.         rcr     cl, 1           ; SnowCheck
  524.         mov     ch, 0           ; Clear CH
  525.         jnc     DFCN_NoWait     ; if no snowcheck goto DFCN_NoWait
  526.  
  527.     DFCN_Top:
  528.         mov     cl, bl          ; Load the number of columns
  529.         call    MoveXY_DI       ; Set DI to screen offset pos
  530.         push    ax              ; Store Registers AX, BX
  531.         push    bx
  532.  
  533.     DFCN_Next:
  534.         cli                     ; Turn off interrupts
  535.         push    dx              ; Save video word
  536.         WaitRetrace             ; Macro - Waits for horiz retrace
  537.         pop     dx              ; Restore video word
  538.         mov     al, dl          ; Move character into al
  539.         stosb                   ; Move word to screen
  540.         sti                     ; Enable interrupts
  541.         inc     di              ; Skip attr
  542.         loop    DFCN_Next       ; Continue
  543.  
  544.         pop     bx              ; Restore registers BX, AX
  545.         pop     ax
  546.         inc     ah              ; Next row
  547.         dec     bh              ; Decrement the number of rows done
  548.         or      bh, bh          ; Check Number of columns
  549.         jnz     DFCN_Top        ; Do next column if not done
  550.         jmp     DFCN_Exit       ; Exit routine
  551.  
  552.     DFCN_NoWait:
  553.         mov     cl, bl          ; Load the number of columns
  554.         call    MoveXY_DI       ; Set DI to screen offset pos
  555.         push    ax              ; Store the row/col info
  556.         mov     al, dl          ; Move char into ax
  557.     DFCN_NoWaitLoop:
  558.         stosb                   ; Thats it!
  559.         inc     di              ; Skip over attr
  560.         loop    DFCN_NoWaitLoop ; Loop for all columns
  561.         pop     ax              ; Restore the row/col info
  562.         inc     ah              ; Next row
  563.         dec     bh              ; Decrement number of rows done
  564.         or      bh, bh          ; Check number of columns
  565.         jnz     DFCN_NoWait     ; Do next column
  566.  
  567.     DFCN_Exit:
  568.         pop     di              ; Restore registers
  569.         pop     es
  570.         pop     dx
  571.         pop     cx
  572.         pop     bx
  573.         pop     ax
  574.         ret
  575.  
  576.     ENDP DFillCHNA
  577.  
  578.     GLOBAL  DFillAttr:PROC
  579.     PROC    DFillAttr
  580.     ;
  581.     ; This procedure fills an area of the screen with the specified
  582.     ; attribute. Character remains the same.
  583.     ;
  584.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  585.     ;
  586.     ; Input
  587.     ;       AH      = Top Row
  588.     ;       AL      = Left Column
  589.     ;       BH      = Number of rows
  590.     ;       BL      = Number of columns
  591.     ;       DH      = Attribute
  592.     ;
  593.         push    ax                      ; Store Registers
  594.         push    bx
  595.         push    cx
  596.         push    dx
  597.         push    es
  598.         push    di
  599.  
  600.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  601.         mov     cl, [SnowCheck]         ; Move snow check to CL
  602.  
  603.         cld                     ; Clear the direction flag
  604.         rcr     cl, 1           ; SnowCheck
  605.         mov     ch, 0           ; Clear CH
  606.         jnc     DFA_NoWait      ; if no snowcheck goto DFA_NoWait
  607.  
  608.     DFA_Top:
  609.         mov     cl, bl          ; Load the number of columns
  610.         call    MoveXY_DI       ; Set DI to screen offset pos
  611.         push    ax              ; Store Registers AX, BX
  612.         push    bx
  613.  
  614.     DFA_Next:
  615.         cli                     ; Turn off interrupts
  616.         push    dx              ; Save attribute in DH
  617.         WaitRetrace             ; Macro - Waits for horiz retrace
  618.         pop     dx              ; Restore attr
  619.         inc     di              ; Skip character
  620.         mov     al, dh          ; Move attr into al
  621.         stosb                   ; Move attr to screen
  622.         sti                     ; Enable interrupts
  623.         loop    DFA_Next        ; Continue
  624.  
  625.         pop     bx              ; Restore registers BX, AX
  626.         pop     ax
  627.         inc     ah              ; Next row
  628.         dec     bh              ; Decrement the number of rows done
  629.         or      bh, bh          ; Check Number of columns
  630.         jnz     DFA_Top         ; Do next column if not done
  631.         jmp     DFA_Exit        ; Exit routine
  632.  
  633.     DFA_NoWait:
  634.         mov     cl, bl          ; Load the number of columns
  635.         call    MoveXY_DI       ; Set DI to screen offset pos
  636.         push    ax              ; Store the row/col info
  637.         mov     al, dh          ; Move attr into ax
  638.     DFA_NoWaitLoop:
  639.         inc     di              ; Skip over character
  640.         stosb                   ; Thats it!
  641.         loop    DFA_NoWaitLoop  ; Loop for all columns
  642.         pop     ax              ; Restore the row/col info
  643.         inc     ah              ; Next row
  644.         dec     bh              ; Decrement number of rows done
  645.         or      bh, bh          ; Check number of columns
  646.         jnz     DFA_NoWait      ; Do next column
  647.  
  648.     DFA_Exit:
  649.         pop     di              ; Restore registers
  650.         pop     es
  651.         pop     dx
  652.         pop     cx
  653.         pop     bx
  654.         pop     ax
  655.         ret
  656.  
  657.     ENDP DFillAttr
  658.  
  659.     GLOBAL  StoreToMem:PROC
  660.     PROC    StoreToMem
  661.     ;
  662.     ; This procedure moves an image from the screen to the designated
  663.     ; memory area.
  664.     ;
  665.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  666.     ;
  667.     ; Input
  668.     ;       AH      = Top Row
  669.     ;       AL      = Left Column
  670.     ;       BH      = Number of rows
  671.     ;       BL      = Number of columns
  672.     ;       ES:DI   = Memory Destination
  673.     ; Modifies
  674.     ;       DI
  675.     ;
  676.         push    ax
  677.         push    bx
  678.         push    cx
  679.         push    dx
  680.         push    ds              ; Store registers
  681.         push    si
  682.  
  683.         mov cl, [SnowCheck]     ; Move snow check to CL
  684.         mov ds, [BaseOfScreen]  ; Move screen seg to DS mov cl,
  685.  
  686.         cld                     ; Clear the direction flag
  687.         rcr     cl, 1           ; SnowCheck
  688.         mov     ch, 0           ; Clear CH
  689.         jnc     STM_NoWait      ; if no snowcheck goto STM_NoWait
  690.  
  691.     STM_Top:
  692.         mov     cl, bl          ; Load the number of columns
  693.         call    MoveXY_SI       ; Set SI to screen offset pos
  694.         push    ax              ; Store row/column info
  695.         push    bx              ; Store number of row/columns info
  696.     STM_Next:
  697.         lodsw                   ; Get a char/word from screen
  698.         mov     bx, ax          ; Store video word into BX
  699.         cli                     ; Turn off interrupts
  700.         WaitRetrace             ; Macro - Waits for horiz retrace
  701.         mov     ax, bx          ; Move word back to AX...
  702.         stosw                   ; Move word to memory
  703.         sti                     ; Enable interrupts
  704.         loop    STM_Next        ; Continue
  705.         pop     bx              ; Restore number of row/columns info
  706.         pop     ax              ; Restore row/column info
  707.         inc     ah              ; Next row
  708.         dec     bh              ; Decrement the number of rows done
  709.         or      bh, bh          ; Check Number of columns
  710.         jnz     STM_Top         ; Do next column if not done
  711.         jmp     STM_Exit        ; Exit routine
  712.  
  713.     STM_NoWait:
  714.         mov     cl, bl          ; Load the number of columns
  715.         call    MoveXY_SI       ; Set SI to screen offset pos
  716.         rep     movsw           ; Thats it!
  717.         inc     ah              ; Next row
  718.         dec     bh              ; Decrement number of rows done
  719.         or      bh, bh          ; Check number of columns
  720.         jnz     STM_NoWait      ; Do next column
  721.  
  722.     STM_Exit:
  723.         pop     si
  724.         pop     ds
  725.         pop     dx
  726.         pop     cx
  727.         pop     bx
  728.         pop     ax
  729.         ret
  730.  
  731.     ENDP StoreToMem
  732.  
  733.     GLOBAL  StoreToScr:PROC
  734.     PROC    StoreToScr
  735.     ;
  736.     ; This procedure moves an image from memory to the designated
  737.     ; screen location.
  738.     ;
  739.     ; *** IMPORTANT -- CALL GetVideoMode Before using this routine!
  740.     ;
  741.     ; Input
  742.     ;       AH      = Top Row
  743.     ;       AL      = Left Column
  744.     ;       BH      = Number of rows
  745.     ;       BL      = Number of columns
  746.     ;       DS:SI   = Memory Area of image
  747.     ; Modifies
  748.     ;       SI
  749.     ;
  750.         push    ax                      ; Store Registers
  751.         push    bx
  752.         push    cx
  753.         push    dx
  754.         push    es
  755.         push    di
  756.  
  757.         mov     es, [BaseOfScreen]      ; Move screen seg to ES
  758.         mov     cl, [SnowCheck]         ; Move snow check to CL
  759.  
  760.         cld                     ; Clear the direction flag
  761.         rcr     cl, 1           ; SnowCheck
  762.         mov     ch, 0           ; Clear CH
  763.         jnc     STS_NoWait      ; if no snowcheck goto STS_NoWait
  764.  
  765.     STS_Top:
  766.         mov     cl, bl          ; Load the number of columns
  767.         call    MoveXY_DI       ; Set DI to screen offset pos
  768.         push    ax              ; Store Registers AX, BX
  769.         push    bx
  770.  
  771.     STS_Next:
  772.         lodsw                   ; Get a char/word from memory
  773.         mov     bx, ax          ; Store video word into BX
  774.         cli                     ; Turn off interrupts
  775.         WaitRetrace             ; Macro - Waits for horiz retrace
  776.         mov     ax, bx          ; Move word back to AX...
  777.         stosw                   ; Move word to screen
  778.         sti                     ; Enable interrupts
  779.         loop    STS_Next        ; Continue
  780.  
  781.         pop     bx              ; Restore registers BX, AX
  782.         pop     ax
  783.         inc     ah              ; Next row
  784.         dec     bh              ; Decrement the number of rows done
  785.         or      bh, bh          ; Check Number of columns
  786.         jnz     STS_Top         ; Do next column if not done
  787.         jmp     STS_Exit        ; Exit routine
  788.  
  789.     STS_NoWait:
  790.         mov     cl, bl          ; Load the number of columns
  791.         call    MoveXY_DI       ; Set DI to screen offset pos
  792.         rep     movsw           ; Thats it!
  793.         inc     ah              ; Next row
  794.         dec     bh              ; Decrement number of rows done
  795.         or      bh, bh          ; Check number of columns
  796.         jnz     STS_NoWait      ; Do next column
  797.  
  798.     STS_Exit:
  799.         pop     di              ; Restore registers
  800.         pop     es
  801.         pop     dx
  802.         pop     cx
  803.         pop     bx
  804.         pop     ax
  805.         ret
  806.  
  807.     ENDP StoreToScr
  808.  
  809.     GLOBAL CursorOff:PROC
  810.     PROC   CursorOff
  811.     ;
  812.     ; This procedure simply turns the Cursor off
  813.     ;
  814.  
  815.         push    ax
  816.         push    bx
  817.         push    cx
  818.         push    dx
  819.         mov     ah, 03h         ; BIOS INT 10 func 3 (Get Cursor pos)
  820.         int     10h             ; Call INT 10
  821.         or      ch, 0100000b    ; Turn on cursor bit
  822.         mov     ah, 01h         ; BIOS INT 10 func 1 (Set cursor type)
  823.         int     10h             ; Call INT 10
  824.         pop     dx
  825.         pop     cx
  826.         pop     bx
  827.         pop     ax
  828.         ret
  829.     ENDP CursorOff
  830.  
  831.     GLOBAL CursorOn:PROC
  832.     PROC   CursorOn
  833.     ;
  834.     ; This procedure simply turns the Cursor on
  835.     ;
  836.         push    ax
  837.         push    bx
  838.         push    cx
  839.         push    dx
  840.         mov     ah, 03h         ; BIOS INT 10 func 3 (Get Cursor pos)
  841.         int     10h             ; Call INT 10
  842.         and     ch, 1011111b    ; Turn off cursor bit
  843.         mov     ah, 01h         ; BIOS INT 10 func 1 (Set cursor type)
  844.         int     10h             ; Call INT 10
  845.         pop     dx
  846.         pop     cx
  847.         pop     bx
  848.         pop     ax
  849.         ret
  850.  
  851.     ENDP CursorOn
  852.  
  853. END ; Of Video.ASM
  854.  
  855.